package com.wsoft.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.wsoft.core.utils.LoginUserUtil;
import com.wsoft.dto.CodeRulesDto;
import com.wsoft.handler.CodeRuleHandler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * 项目中注入CodeRulesUtil 并调用 initCode方法
 * @Author z001
 * @Date 2024/10/17 08:25
 */
@Component
public class CodeRulesUtil {

    /**
     * 补位字符
     */
    public static final String PAD_CHAR = "0";
    /**
     * 自动长度 默认为0
     */
    private static final int AUTO_LENGTH = 0;

    @Resource
    private CodeRuleHandler codeRuleHandler;

    /**
     * 初始化 code
     * @param code 生成code编码规则的code值
     * @param objectJson 对象json
     * @param isUsed 是否保存数据库(0-不保存,1-保存)
     * @return
     * @throws Exception
     */
    public Object initCode(String code, JSONObject objectJson, Integer isUsed) {
        return codeRuleHandler.execute(code, objectJson, isUsed);
    }

    /**
     * 删除code
     * @param code 生成code编码规则的code值
     * @param value 需要删除的code值
     */
    public void delCode(String code, String value){
        codeRuleHandler.deleteCode(code,value);
    }


    //############################### 构建code begin######################################################
    /**
     * 构建常量code
     *
     * @param dto
     * @return
     */
    public static String buildConstant(CodeRulesDto dto) {
        return computeLength(dto.getLength(), dto.getValue(),dto.getValue().toString());
    }

    /**
     * 构建 补位常量
     * @param dto
     * @return
     */
    public static String buildCoverConstant() {
        //补位常量  返回补位占位符 {}
        return StrUtil.DELIM_START + StrUtil.DELIM_END;
    }

    /**
     * 构建组织编码
     * @param dto
     * @return
     */
    public static String buildOrgCode(CodeRulesDto dto, List<Integer> templateIndex) {
        //获取当前登录人组织编码
        String orgCode = LoginUserUtil.getUserInfo().getLoginUserVO().getLoginOrgCode();
        if(StrUtil.isBlank(orgCode)){
            return null;
        }
        templateIndex.add(dto.getIndex());
        return computeLength(dto.getLength(), orgCode,PAD_CHAR);
    }

    /**
     * 构建用户编码
     * @param dto
     * @return
     */
    public static String buildUserCode(CodeRulesDto dto, List<Integer> templateIndex) {
        //获取当前登录人用户编码
        String userCode = LoginUserUtil.getUserInfo().getLoginUserVO().getCode();
        if(StrUtil.isBlank(userCode)){
            return null;
        }
        templateIndex.add(dto.getIndex());
        return computeLength(dto.getLength(), userCode,PAD_CHAR);
    }

    /**
     * 构建流水号
     * @param dto
     * @param templateIndex
     * @return
     */
    public static String buildSerialNumber() {
        //返回流水占位符 []
        return StrUtil.BRACKET_START + StrUtil.BRACKET_END;
    }

    /**
     * 构建随机数
     * @param dto
     * @return
     */
    public static String buildRandomCode(CodeRulesDto dto) {
        return RandomUtil.randomNumbers(dto.getLength());
    }

    /**
     * 构建系统时间
     * @param dto
     * @return
     */
    public static String buildSystemDate(CodeRulesDto dto,List<Integer> templateIndex) {
        String format = DateUtil.format( DateUtil.date(), dto.getValue().toString());
        templateIndex.add(dto.getIndex());
        return computeLength(dto.getLength(), format,PAD_CHAR);
    }

    /**
     * 构建 单据元素
     * @param dto
     * @param objectJson
     * @return
     */
    public static String buildPageElements(CodeRulesDto dto,JSONObject objectJson,List<Integer> templateIndex) {
        Object value = objectJson.get(dto.getValue());
        templateIndex.add(dto.getIndex());
        return computeLength(dto.getLength(), value,PAD_CHAR);
    }

    //############################### 构建code end######################################################



    /**
     * 计算编码长度
     * @param length 编码指定长度
     * @param value 编码值
     * @param padChar 补位常量
     * @return 新的编码值 长度等于length
     */
    public static String computeLength(int length,Object value,String padChar){
        if(ObjUtil.isEmpty(value)){
            return null;
        }
        if(StrUtil.isBlank(padChar)){
            padChar = PAD_CHAR;
        }
        String valueString = value.toString();
        int valueLength = valueString.length();
        if(length == AUTO_LENGTH || length == valueLength){
            //自动长度 或者 和指定长度相等
            return valueString;
        }else if(length > valueLength){
            //指定长度 大于value  前面补值 20 ==> 020
            return StrUtil.padPre(valueString, length, padChar);
        }else{
            //指定长度 小于value  前面截取 abc ==> bc
            return valueString.substring(valueLength-length);
        }
    }




    public static void main(String[] args) {
        System.out.println(StrUtil.padPre("020", 5, "a"));
    }

}
